#pragma once
#include <map>
#include <string>
#if (defined(__clang__) && defined(_LIBCPP_VERSION)) || (__cplusplus >= 201103L)
#include <memory>
#else
#include <tr1/memory>
#endif
#include <pthread.h>

struct BBS2chProxyThreadInfo
{
	int lastResNum;
	int cachedSize;
	std::string cachedData;
	BBS2chProxyThreadInfo() : lastResNum(0), cachedSize(0) {};
	~BBS2chProxyThreadInfo() {};
};

struct BBS2chThreadIdentifier {
	std::string hostPrefix;
	std::string host;
	std::string board;
	std::string key;
};

#if (defined(__clang__) && defined(_LIBCPP_VERSION)) || (__cplusplus >= 201103L)
typedef std::shared_ptr<BBS2chProxyThreadInfo> PBBS2chProxyThreadInfo;
#else
typedef std::tr1::shared_ptr<BBS2chProxyThreadInfo> PBBS2chProxyThreadInfo;
#endif

class BBS2chProxyThreadCache
{
private:
	pthread_mutex_t _mutex;
	std::map<std::string, PBBS2chProxyThreadInfo> _cache;
public:
	BBS2chProxyThreadCache() {
		pthread_mutex_init(&_mutex, NULL);
	}
	~BBS2chProxyThreadCache() {
		pthread_mutex_destroy(&_mutex);
	}
	void set(const std::string &key, PBBS2chProxyThreadInfo info) {
		pthread_mutex_lock(&_mutex);
		_cache.insert(std::make_pair(key, info));
		pthread_mutex_unlock(&_mutex);
	}
	PBBS2chProxyThreadInfo get(const std::string &key) {
		PBBS2chProxyThreadInfo info;
		pthread_mutex_lock(&_mutex);
		std::map<std::string, PBBS2chProxyThreadInfo>::iterator it = _cache.find(key);
		if(it != _cache.end()) {
			info = it->second;
		}
		pthread_mutex_unlock(&_mutex);
		return info;
	}
	PBBS2chProxyThreadInfo pop(const std::string &key) {
		PBBS2chProxyThreadInfo info;
		pthread_mutex_lock(&_mutex);
		std::map<std::string, PBBS2chProxyThreadInfo>::iterator it = _cache.find(key);
		if(it != _cache.end()) {
			info = it->second;
			_cache.erase(it);
		}
		pthread_mutex_unlock(&_mutex);
		return info;
	}
	void remove(const std::string &key) {
		pthread_mutex_lock(&_mutex);
		std::map<std::string, PBBS2chProxyThreadInfo>::iterator it = _cache.find(key);
		if(it != _cache.end()) {
			_cache.erase(it);
		}
		pthread_mutex_unlock(&_mutex);
	}
};
